/**
 * Copyright 2010 Tristan Slominski
 *
 * Licensed under the MIT License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.opensource.org/licenses/mit-license.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mindash.handlebars.client.views.impl;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Provider;
import com.mindash.handlebars.client.views.View;
import com.mindash.handlebars.client.views.ViewFactory;

/**
 * @author Tristan Slominski
 * 
 */
public abstract class DefaultViewFactoryImpl extends DefaultViewImpl implements
    ViewFactory {

  /* variables */
  private Map<Integer, Provider<View>> providers =
      new HashMap<Integer, Provider<View>>();
  private Map<Integer, View> views = new HashMap<Integer, View>();

  @SuppressWarnings("unchecked")
  @Override
  public <V extends View> void addViewProvider(int adapter,
      Provider<V> viewProvider) {
    getProviders().put(adapter, (Provider<View>) viewProvider);
  }

  @Override
  public Widget createAndBind() {
    bindView();
    
    int adapter = getPresenter().getAdapter();
    View view = getView(adapter);
    if (view != null) {
      view.setPresenter(getPresenter());
      return view.createAndBind();
    }
    return null;
  }

  @SuppressWarnings("unchecked")
  @Override
  public <V extends View> V getView(int adapter) {
    V view = (V) getViews().get(adapter);
    if (view == null){
      Provider<View> provider = getProviders().get(adapter);
      getViews().put(adapter, provider.get());
      view = (V) getViews().get(adapter);
    }
    return view;
  }

  /* getters and setters */
  
  public Map<Integer, Provider<View>> getProviders() {
    return providers;
  }

  public Map<Integer, View> getViews() {
    return views;
  }

  public void setProviders(Map<Integer, Provider<View>> providers) {
    this.providers = providers;
  }

  public void setViews(Map<Integer, View> views) {
    this.views = views;
  }

}
